const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const path = require('path');
const cors = require('cors');
const { v4: uuidv4 } = require('uuid');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
    cors: {
        origin: "*",
        methods: ["GET", "POST"]
    }
});

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.static(path.join(__dirname, '..')));

// 游戏状态存储
const gameRooms = new Map();
const playerSessions = new Map();

// 房间管理
class GameRoom {
    constructor(code) {
        this.code = code;
        this.players = new Map();
        this.worldState = this.generateWorld();
        this.maxPlayers = 8;
        this.createdAt = Date.now();
    }

    generateWorld() {
        const world = {
            blocks: new Map(),
            players: new Map()
        };
        
        // 生成基础地形
        for (let x = 0; x < 32; x++) {
            for (let y = 15; y < 32; y++) {
                const blockType = y < 20 ? 1 : 2; // 1=草地, 2=泥土
                world.blocks.set(`${x},${y}`, blockType);
            }
        }
        
        // 添加一些矿石
        for (let i = 0; i < 50; i++) {
            const x = Math.floor(Math.random() * 32);
            const y = 20 + Math.floor(Math.random() * 12);
            const oreType = Math.floor(Math.random() * 3) + 3; // 3=煤, 4=铁, 5=金
            world.blocks.set(`${x},${y}`, oreType);
        }
        
        return world;
    }

    addPlayer(playerId, playerData) {
        if (this.players.size >= this.maxPlayers) {
            return false;
        }
        
        this.players.set(playerId, {
            ...playerData,
            x: Math.random() * 512,
            y: 100,
            inventory: {
                wood: 0,
                stone: 0,
                coal: 0,
                iron: 0,
                gold: 0
            }
        });
        
        return true;
    }

    removePlayer(playerId) {
        this.players.delete(playerId);
    }

    updatePlayerPosition(playerId, x, y) {
        const player = this.players.get(playerId);
        if (player) {
            player.x = x;
            player.y = y;
        }
    }

    updateBlock(x, y, type, action) {
        const key = `${x},${y}`;
        
        if (action === 'mine') {
            this.worldState.blocks.delete(key);
        } else if (action === 'place') {
            this.worldState.blocks.set(key, type);
        }
        
        return true;
    }

    getState() {
        return {
            code: this.code,
            players: Array.from(this.players.values()),
            worldState: Object.fromEntries(this.worldState.blocks),
            playerCount: this.players.size,
            maxPlayers: this.maxPlayers
        };
    }
}

// Socket.IO连接处理
io.on('connection', (socket) => {
    console.log('玩家连接:', socket.id);
    
    socket.on('join-room', (data) => {
        const { roomCode, username } = data;
        
        let room = gameRooms.get(roomCode);
        if (!room) {
            room = new GameRoom(roomCode);
            gameRooms.set(roomCode, room);
        }
        
        const playerData = {
            id: socket.id,
            username: username,
            socket: socket
        };
        
        if (room.addPlayer(socket.id, playerData)) {
            socket.join(roomCode);
            playerSessions.set(socket.id, { roomCode, username });
            
            // 发送房间状态给新玩家
            socket.emit('room-joined', room.getState());
            
            // 通知其他玩家
            socket.to(roomCode).emit('player-joined', {
                id: socket.id,
                username: username,
                x: room.players.get(socket.id).x,
                y: room.players.get(socket.id).y
            });
            
            console.log(`玩家 ${username} 加入房间 ${roomCode}`);
        } else {
            socket.emit('room-full');
        }
    });
    
    socket.on('player-move', (data) => {
        const session = playerSessions.get(socket.id);
        if (!session) return;
        
        const room = gameRooms.get(session.roomCode);
        if (room) {
            room.updatePlayerPosition(socket.id, data.x, data.y);
            socket.to(session.roomCode).emit('player-moved', {
                id: socket.id,
                x: data.x,
                y: data.y
            });
        }
    });
    
    socket.on('block-update', (data) => {
        const session = playerSessions.get(socket.id);
        if (!session) return;
        
        const room = gameRooms.get(session.roomCode);
        if (room) {
            room.updateBlock(data.x, data.y, data.type, data.action);
            socket.to(session.roomCode).emit('block-updated', data);
        }
    });
    
    socket.on('save-game', (data) => {
        const session = playerSessions.get(socket.id);
        if (!session) return;
        
        // 保存玩家数据到房间
        const room = gameRooms.get(session.roomCode);
        if (room && room.players.has(socket.id)) {
            const player = room.players.get(socket.id);
            player.inventory = data.inventory;
            player.x = data.playerPosition.x;
            player.y = data.playerPosition.y;
        }
        
        // 这里可以添加数据库保存逻辑
        console.log(`保存玩家 ${session.username} 的游戏数据`);
    });
    
    socket.on('disconnect', () => {
        const session = playerSessions.get(socket.id);
        if (session) {
            const room = gameRooms.get(session.roomCode);
            if (room) {
                room.removePlayer(socket.id);
                socket.to(session.roomCode).emit('player-left', socket.id);
                
                // 如果房间为空，删除房间
                if (room.players.size === 0) {
                    gameRooms.delete(session.roomCode);
                    console.log(`房间 ${session.roomCode} 已删除`);
                }
            }
            
            playerSessions.delete(socket.id);
            console.log(`玩家 ${session.username} 断开连接`);
        }
    });
});

// API路由
app.get('/api/rooms', (req, res) => {
    const rooms = Array.from(gameRooms.values()).map(room => ({
        code: room.code,
        playerCount: room.players.size,
        maxPlayers: room.maxPlayers,
        createdAt: room.createdAt
    }));
    
    res.json(rooms);
});

app.get('/api/room/:code', (req, res) => {
    const room = gameRooms.get(req.params.code);
    if (room) {
        res.json(room.getState());
    } else {
        res.status(404).json({ error: '房间不存在' });
    }
});

// 健康检查
app.get('/health', (req, res) => {
    res.json({ 
        status: 'ok', 
        rooms: gameRooms.size,
        players: playerSessions.size,
        uptime: process.uptime()
    });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
    console.log(`服务器运行在端口 ${PORT}`);
    console.log(`游戏地址: http://localhost:${PORT}`);
});

// 定期清理空房间
setInterval(() => {
    const now = Date.now();
    for (const [code, room] of gameRooms.entries()) {
        if (room.players.size === 0 && now - room.createdAt > 3600000) { // 1小时
            gameRooms.delete(code);
            console.log(`清理空房间: ${code}`);
        }
    }
}, 60000); // 每分钟检查一次